﻿using MaterialDesignThemes.Wpf;

namespace 算法入门.DialogsFolder
{
    public class DialogHostService : DialogService, IDialogHostService
    {
        private readonly IContainerExtension _containerExtension;

        public DialogHostService(IContainerExtension containerExtension)
            : base(containerExtension)
        {
            this._containerExtension = containerExtension;
        }

        public void RefreshData(string name,
                                IDialogParameters parameters,
                                string dialogHostName = "RootDialog")
        {
            if (parameters == null)
                parameters = new DialogParameters();

            //根据注册的ViewModel的名称解析出对话框的视图
            //例如:待办事项    name 为:AddToDoViewModel   视图为:AddToDo
            var content = _containerExtension.Resolve<object>(name);
            if (!(content is FrameworkElement dialogContent))
                throw new NullReferenceException("A dialog's content must be a FrameworkElement");

            //解析出来的视图是FrameworkElement类型
            //自动为该视图设置ViewModel
            if (dialogContent is FrameworkElement view && view.DataContext is null
                && ViewModelLocator.GetAutoWireViewModel(view) is null)
            {
                ViewModelLocator.SetAutoWireViewModel(view, true);
            }

            //ViewModel必须实现了自定义的 IDialogHostAware 接口
            if (!(dialogContent.DataContext is IDialogHostAware viewModel))
                throw new NullReferenceException("A dialog's ViewModel must implement the IDialogAware interface");

            //因为AddToDoViewModel是实现了IDialogHostAware接口
            if (viewModel is IDialogHostAware aware)
            {
                //调用自定义OnDialogOpend方法给ViewModel传递参数
                aware.RefreshData();
            }

        }

        public async Task<IDialogResult> ShowDialog(string name,
                                                    IDialogParameters parameters,
                                                    string dialogHostName = "RootDialog")
        {
            if (parameters == null)
                parameters = new DialogParameters();

            //根据注册的ViewModel的名称解析出对话框的视图
            //例如:待办事项    name 为:AddToDoViewModel   视图为:AddToDo
            var content = _containerExtension.Resolve<object>(name);
            if (!(content is FrameworkElement dialogContent))
                throw new NullReferenceException("A dialog's content must be a FrameworkElement");

            //解析出来的视图是FrameworkElement类型
            //自动为该视图设置ViewModel
            if (dialogContent is FrameworkElement view && view.DataContext is null
                && ViewModelLocator.GetAutoWireViewModel(view) is null)
            {
                ViewModelLocator.SetAutoWireViewModel(view, true);
            }

            //ViewModel必须实现了自定义的 IDialogHostAware 接口
            if (!(dialogContent.DataContext is IDialogHostAware viewModel))
                throw new NullReferenceException("A dialog's ViewModel must implement the IDialogAware interface");

            //设置DialogHostName
            viewModel.DialogHostName = dialogHostName;

            //DialogOpenedEventHandler  为DialogHost 的参数，它是Masterial控件里面的
            DialogOpenedEventHandler dialogOpenedEventHandler = (s, e) =>
            {
                //因为AddToDoViewModel是实现了IDialogHostAware接口
                if (viewModel is IDialogHostAware aware)
                {
                    //调用自定义OnDialogOpend方法给ViewModel传递参数
                    aware.OnDialogOpend(parameters);
                }
                //更新对话框内容到对话框控件上
                e.Session.UpdateContent(content);
            };

            //打开对话框,注意DialogHost是个对话框的宿主,可以调用它的show方法打开一个对话框，
            //通过dialogContent设置内容
            //dialogHostName必须为DialogHost的Identifier
            //在这里是MainWindow.xaml里面的 RootDialog
            //< materialDesign:DialogHost
            //Identifier = "RootDialog"
            var dialogResult = (IDialogResult)await DialogHost
                .Show(dialogContent, dialogHostName, dialogOpenedEventHandler);

            return dialogResult;
        }
    }
}
